/*
 * CopyRight  : (C)2012-2099 HaoTeam Inc.
 * Document   : formCreate.js
 * Created on : 2021-1-31 22:28:43
 * Author     : Tiger <1192851302@qq.com>
 * Description: This is NOT a freeware, use is subject to license terms.
 *              这即使是一个免费软件,使用时也请遵守许可证条款,得到当时人书面许可.
 *              未经书面许可,不得翻版,翻版必究;版权归属 HaoTeam Inc;
 */
layui.define(['jquery', 'layer', 'laydate', 'upload'], function (exports) {
    var MOD_NAME = 'formCreate',
            o = layui.jquery
            , laydate = layui.laydate
            , upload = layui.upload
            , layer = layui.layer
            , formCreate = {}
    //操作当前实例
    , thisIns = function () {
        var that = this, options = that.config;
        return {
            config: options
        };
    }

    //构造器
    , Class = function (options) {
        var that = this;
        that.config = o.extend({}, that.config, options);
        that.render();
    };

    //默认配置
    Class.prototype.config = {
        FILEUPLOADURL: 'http://www.admin.com/index.php/admin/file/upload/file'//文件上传地址
        , IMAGEUPLOADURL: 'http://www.admin.com/index.php/admin/file/upload/image'//图片上传地址
        , request: {
            tokenName: ""//TOKEN名称
            , TOKEN: ''//TOKEN值
        }
    };

    Class.prototype.render = function () {
        var html = '', that = this, options = that.config;
        o.each(options.data, function (index, item) {
            //console.log(item);
            switch (item.type) {
                case 'text':
                case 'password':
                case 'number':
                    html += that.inputCreate(item);
                    break;
                case 'year':
                case 'month':
                case 'date':
                case 'time':
                case 'datetime':
                    html += that.dateCreate(item);
                    break;
                case 'upload':
                    html += that.uploadCreate(item);
                    break;
                case 'select':
                    html += that.selectCreate(item);
                    break;
                case 'switch':
                case 'checkbox':
                case 'radio':
                    html += that.radioCreate(item);
                    break;
                case 'textarea':
                    html += that.textareaCreate(item);
                    break;
                default:
                    break;
            }
        });
        var $dom = o(options.elem);
        $dom.html(html);
        /*! 显示必填 */
        $dom.find('[lay-verify*="required"]').map(function ($parent) {
            if (($parent = o(this).parent()) && $parent.is('label')) {
                $parent.addClass('label-required-prev');
            } else {
                if (o(this).is('label')) {
                    o(this).addClass('label-required-next');
                } else {
                    $parent.prevAll('label').addClass('label-required-next');
                }
            }
        });
        $dom.find('input[data-date]').map(function () {
            laydate.render({
                type: this.getAttribute('data-date') || 'date',
                range: false, elem: this, done: function (value) {
                    o(this.elem).val(value).trigger('change');
                }
            });
        });
        $dom.find('input[data-date-range]').map(function () {
            laydate.render({
                type: this.getAttribute('data-date-range') || 'date',
                range: true, elem: this, done: function (value) {
                    o(this.elem).val(value).trigger('change');
                }
            });
        });
        /*! 初始化上传 */
        $dom.find('[data-file]:not([data-inited])').map(function (index, elem, $this, field) {
            $this = o(elem), field = $this.attr('data-name') || 'file';
            if (!$this.data('input')) {
                $this.data('input', o('[name="' + field + '"]').get(0));
            }
            that.uploadFile($this, function (url) {
                o($this.data('input')).val(url).trigger('change');
            });
        });
        if (typeof options.callback === 'function' && options.callback.call(that, $dom) === false) {
            return false;
        }
        return $dom;
    };
    Class.prototype.inputCreate = function (data) {
        var html = '', that = this;
        html = that.inputHeader(data.title) +
                '<input type="' + data.type + '" name="' + data.name + '"  value="' + (data.value === null || data.value === undefined ? '' : data.value) + '" lay-verify="' + that.inputVerify(data.rules) + '" placeholder="请输入' + data.title + '" autocomplete="off" class="layui-input">' +
                that.inputTail(data.descs);
        return html;
    };
    Class.prototype.dateCreate = function (data) {
        var html = '', that = this;
        html = that.inputHeader(data.title);
        if (data.params) {
            html += '<input type="text" data-date-range="' + data.type + '" id="' + data.name + '" name="' + data.name + '"  value="' + (data.value === null || data.value === undefined ? '' : data.value) + '" lay-verify="' + that.inputVerify(data.rules) + '" placeholder="请输入' + data.title + '" autocomplete="off" class="layui-input">';
        } else {
            html += '<input type="text" data-date="' + data.type + '" id="' + data.name + '" name="' + data.name + '"  value="' + (data.value === null || data.value === undefined ? '' : data.value) + '" lay-verify="' + that.inputVerify(data.rules) + '" placeholder="请输入' + data.title + '" autocomplete="off" class="layui-input">';
        }
        return html + that.inputTail(data.descs);
    };
    Class.prototype.uploadCreate = function (data) {
        var html = '', that = this;
        if (data.params === null) {
            return html;
        }
        var params = that.getJson(data.params);
        html = that.inputHeader(data.title);
        //console.log(params.multiple);
        if ((params.multiple === "false" || typeof params.multiple == "undefined") && (params.accept === 'images' || typeof params.accept === "undefined")) {
            html += '<div id="' + data.name + '_box" style="display: flex;">\n\
<input type="hidden" data-size="' + (params.size || 512) + '" name="' + data.name + '"  value="' + (data.value === null || data.value === undefined ? '' : data.value) + '" lay-verify="' + that.inputVerify(data.rules) + '">\n\
<script>layui.jquery(\'input[name="' + data.name + '"]\').uploadOneImage();</script></div>';
        } else if (params.multiple === "true" && (params.accept === 'images' || typeof params.accept === "undefined")) {
            html += '<div id="' + data.name + '_box" style="display: flex;">\n\
<input type="hidden" data-number="' + (params.number || 2) + '" data-size="' + (params.size || 512) + '" name="' + data.name + '"  value="' + (data.value === null || data.value === undefined ? '' : data.value) + '" lay-verify="' + that.inputVerify(data.rules) + '">\n\
<script>layui.jquery(\'input[name="' + data.name + '"]\').uploadMultipleImage();</script></div>';
        } else if ((params.multiple === "false" || typeof params.multiple == "undefined") && params.accept === 'file') {
            html += '<div id="' + data.name + '_box" style="display: flex;">\n\
<input type="text" data-exts="' + (params.exts || 'pem|jpg|png|jpeg') + '" data-size="' + (params.size || 512) + '" name="' + data.name + '"  value="' + (data.value === null || data.value === undefined ? '' : data.value) + '"  lay-verify="' + that.inputVerify(data.rules) + '" placeholder="请输入' + data.title + '" autocomplete="off" class="layui-input">\n\
<script>layui.jquery(\'input[name="' + data.name + '"]\').uploadOneFile();</script></div>';
        }
        return html + that.inputTail(data.descs);
    };
    Class.prototype.selectCreate = function (data) {
        var html = '', that = this;
        if (data.params === null) {
            return html;
        }
        html = '<select name="' + data.name + '" lay-verify="' + that.inputVerify(data.rules) + '"><option value="">请选择' + data.title + '</option>';
        o.each(that.getJson(data.params), function (key, item) {
            if (item === " " || item === null || typeof (item) === "undefined") {
                return true;
            }
            var checked = '';
            if (data.value == key) {
                checked = ' selected="selected"';
            }
            html += '<option value="' + key + '"' + checked + '>' + item + '</option>';
        });
        html += '</select>';
        return  that.inputHeader(data.title) + html + that.inputTail(data.descs);
    };
    Class.prototype.radioCreate = function (data) {
        var html = '', that = this;
        if (data.params === null) {
            return html;
        }
        o.each(that.getJson(data.params), function (key, item) {
            if (item === " " || item === null || typeof (item) === "undefined") {
                return true;
            }
            var checked = '';
            if (data.value == key) {
                checked = ' checked';
            }
            html += '<input type="' + data.type + '" name="' + data.name + '" value="' + key + '" title="' + item + '" ' + checked + '>';
        });
        return  that.inputHeader(data.title) + html + that.inputTail(data.descs);
    };
    Class.prototype.textareaCreate = function (data) {
        var html = '', that = this;
        html = that.inputHeader(data.title) +
                '<textarea lay-verify="' + that.inputVerify(data.rules) + '" name="' + data.name + '" placeholder="请输入' + data.title + '" class="layui-textarea">' + (data.value === null || data.value === undefined ? '' : data.value) + '</textarea>'
                + that.inputTail(data.descs);
        //console.log(data);
        return html;
    };
    Class.prototype.inputVerify = function (rules) {
        var verify = '', param;
        if (rules) {
            param = rules.split("|");
            o.each(param, function (index, item) {
                if (['required', 'phone', 'email', 'url', 'number', 'date', 'identity'].includes(item)) {
                    verify += item + '|';
                }
            });
            return verify.substring(0, verify.length - 1);
        }
        return '';
    };
    Class.prototype.inputHeader = function (title) {
        return '<div class="layui-form-item"><label class="layui-form-label">' + title + '</label><div class="layui-input-inline">';
    };
    Class.prototype.inputTail = function (descs) {
        return descs ? '<p class="help-block">' + descs + '</p></div></div>' : '</div></div>';
    };
    Class.prototype.rowTurnArray = function (string) {
        var param = [], params = [];
        param = string.split(/[(\r\n)\r\n]+/);
        params = param.map((ele) => ele.split('='));
        //console.log(params);
        return params;
    };
    Class.prototype.getJson = function (string) {
        var param = [], params = [];
        param = string.split(/[(\r\n)\r\n]+/);
        params = param.map((ele) => ele.split('='));
        var array = params.reduce(function (pre, cur) {
            pre[cur[0]] = decodeURIComponent(cur[1]);
            return pre;
        }, []);
        return array;
    };
    /*! 全局文件上传入口 */
    Class.prototype.uploadFile = function ($this, callback) {
        var that = this;
        var fileCount = 0;//控制文件数量
        var load;
        var options = {};
        if ($this.attr('data-inited')) {
            return false;
        }
        $this.attr('data-inited', true);
        options.headers = options.headers || {};
        if (that.config.request.tokenName) {
            //自动给 Request Headers 传入 token
            options.headers[that.config.request.tokenName] = that.config.request.TOKEN;
        }
        options.multiple = $this.attr('data-file') === "images" || $this.attr('data-file') === "files" ? true : false;
        if (options.multiple === true) {
            options.number = $this.attr('data-number') || 2;
            options.auto = false;
            options.allDone = function (obj) { //当文件全部被提交后，才触发
                //console.log('得到总文件数', obj.total); //得到总文件数
                //console.log('请求成功的文件数', obj.successful); //
                //.log('请求失败的文件数', obj.aborted); //
            };
        }

        var json = {
            elem: '#' + $this.attr('id')
            , url: ['image', 'images'].includes($this.attr('data-field')) ? that.config.IMAGEUPLOADURL : that.config.FILEUPLOADURL
            , accept: $this.attr('data-accept') || 'images' //普通文件
            , exts: $this.attr('data-exts') || 'jpg|png|jpeg'
            , field: $this.attr('data-field') || 'image'
            , size: $this.attr('data-size') || 500
            , data: JSON.parse($this.attr('data-param')) || {}
            , before: function (input) {

            }
            , done: function (res) {
                if (res.code === 200) {
                    return  callback(res.data.url);
                }
                layer.msg(res.msg);
            }
            , error: function (index, upload) {
                console.log('当上传失败时', index, upload);
            }
            , choose: function (input) {
                if (options.multiple === false) {
                    return false;
                }
                fileCount = o("#" + $this.attr('data-name') + "_box").children(".uploadimagemtl").length;
                //将每次选择的文件追加到文件队列
                var files = input.pushFile();
                //console.log(input);
                //预读本地文件，如果是多文件，则会遍历。(不支持ie8/9)
                input.preview(function (index, file, result) {
                    //这里还可以做一些 append 文件列表 DOM 的操作
                    fileCount++;
                    if (fileCount > options.number) {
                        fileCount--;
                        layer.msg('文件数量不得超过' + options.number + '个');
                        delete files[index]; //删除列表中对应的文件，一般在某个事件中使用
                    } else {
                        input.upload(index, file); //上传
                    }
                });
            }
        };
        options = o.extend(json, options);
        var uploadInst = upload.render(options);
    };
    /*! 上传单个文件 */
    o.fn.uploadOneFile = function () {
        var name = o(this).attr('name') || 'file';
        var $tpl = o('<button data-file="file" data-accept="file" data-field="file" type="button" class="margin-left-sm layui-btn layui-btn-normal"><i class="layui-icon"></i>上传文件</button>')
                .attr('id', name)
                .attr('data-name', name)
                .attr('data-param', this.attr('data-param') || "{}")
                .attr('data-size', this.attr('data-size'))
                .attr('data-exts', this.attr('data-exts'));
        o(this).after($tpl.data('input', this)).on('change', function () {
            if (this.value) {
            }
        }).trigger('change');
    };
    /*! 上传单个图片 */
    o.fn.uploadOneImage = function () {
        var name = o(this).attr('name') || 'image';
        var originalValue = o('[name="' + name + '"]').val() || '';
        var $tpl = o('<a data-file="image" class="uploadimage"></a>')
                .attr('id', name)
                .attr('data-name', name)
                .attr('data-param', this.attr('data-param') || "{}")
                .attr('data-size', this.attr('data-size') || 500);
        if (originalValue) {
            $tpl.css('backgroundImage', 'url(' + originalValue + ')');
        }
        o(this).after($tpl.data('input', this)).on('change', function () {
            if (this.value) {
                $tpl.css('backgroundImage', 'url(' + this.value + ')');
            }
        }).trigger('change');
    };
    /*! 上传多个图片 */
    o.fn.uploadMultipleImage = function () {
        var name = o(this).attr('name') || 'images';
        var $tpl = o('<a data-file="images" class="uploadimage"></a>')
                .attr('id', name)
                .attr('data-name', name)
                .attr('data-param', this.attr('data-param') || "{}")
                .attr('data-size', this.attr('data-size') || 500)
                .attr('data-number', this.attr('data-number') || 2);
        o(this).attr('name', name).after($tpl.data('input', this)).on('change', function () {
            var input = this;
            this.setImageData = function () {
                input.value = input.getImageData().join('|');
            };
            this.getImageData = function () {
                var values = [];
                o(input).prevAll('.uploadimage').map(function () {
                    values.push(o(this).attr('data-tips-image'));
                });
                return values.reverse(), values;
            };
            var urls = this.getImageData(), srcs = this.value.split('|');
            for (var i in srcs)
                if (srcs[i])
                    urls.push(srcs[i]);
            o(this).prevAll('.uploadimage').remove();
            this.value = urls.join('|');
            for (var i in urls) {
                var tpl = '<div class="uploadimage uploadimagemtl">\n\
<div class="change_"><a class="layui-icon margin-right-5">&#xe602;</a><a class="layui-icon margin-right-5">&#x1006;</a><a class="layui-icon margin-right-5">&#xe603;</a></div></div>';
                var $tpl = o(tpl).attr('data-tips-image', urls[i]).css('backgroundImage', 'url(' + urls[i] + ')').on('click', 'a', function (e) {
                    e.stopPropagation();
                    var $cur = o(this).parent();
                    switch (o(this).index()) {
                        case 1:// remove
                            return layer.confirm('确定要移除这张图片吗？', function (index) {
                                $cur.remove(), input.setImageData();
                            });
                        case 0: // right
                            var lenght = $cur.siblings('div.uploadimagemtl').length;
                            if ($cur.index() !== lenght)
                                $cur.next().after($cur);
                            return input.setImageData();
                        case 2: // left
                            if ($cur.index() !== 0)
                                $cur.prev().before($cur);
                            return input.setImageData();
                    }
                });
                o(this).before($tpl);
            }
        }).trigger('change');
    };
    //核心入口
    formCreate.render = function (options) {
        var ins = new Class(options);
        return thisIns.call(ins);
    };
    exports(MOD_NAME, formCreate);
});